#ifndef _NETWORK_MEM_H_
#define _NETWORK_MEM_H_

#include <map>
#include <set>
#include <vector>
#include <list>
#include <queue>
#include <string>
#include <sstream>
#include <memory.h>
//#include <typeinfo>
#include "cache.h"

namespace Cross
{
#ifndef USE_GOOGLE_TCMALLOC
#ifdef _DEBUG
MemoryAllocator<true,true> *GetAllocator();
#else
MemoryAllocator<true,false> *GetAllocator();
#endif
#else
DummyAllocator* GetAllocator();
#endif
template<class T>
class UserSTLAllocator
{
public:
  typedef T value_type;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  typedef T* pointer;
  typedef const T* const_pointer;
  typedef T& reference;
  typedef const T& const_reference;
  pointer address(reference r) const{return &r;}
  const_pointer address(const_reference r) const{return &r;}
  void construct(pointer p,const T &val){new(p) T(val);}
  void construct(pointer p){new(p) T();}
  void destroy(pointer p){p->~T();}
  size_type max_size() const throw(){return size_type(-1)/sizeof(T);}
  template<class U> struct rebind{typedef UserSTLAllocator<U> other;};
public:
  UserSTLAllocator() throw(){}
  template<class U> UserSTLAllocator(const UserSTLAllocator<U> &) throw(){}
  ~UserSTLAllocator() throw(){}
  pointer allocate(size_type n,const_pointer hint=0)
  {
    return (pointer)GetAllocator()->alloc(n*sizeof(T));
  }
  void deallocate(pointer p,size_type n)
  {
    GetAllocator()->free(p,n*sizeof(T));
  }
};
template<class T,class U> inline bool operator==(const UserSTLAllocator<T> &,const UserSTLAllocator<U> &){return true;}
template<class T,class U> inline bool operator!=(const UserSTLAllocator<T> &,const UserSTLAllocator<U> &){return false;}

class StackMemory
{
public:
    explicit StackMemory(size_t s)
    {
        _p=GetAllocator()->alloc(s);
        _s=s;
    }
    ~StackMemory()
    {
        if(_p)
            GetAllocator()->free(_p,_s);
    }
    void Zero(){memset(_p,0,_s);}
    size_t Size(){return _s;}
    void* Get(){return _p;}
    template<class T> T* Get(){return (T*)_p;}
private:
    void* _p;
    size_t _s;
};

}




template<class K,class V,class Cmp=std::less<K> >
struct STLMap
{
  typedef std::map<K,V,Cmp,Cross::UserSTLAllocator<std::pair<const K,V> > > type;
};

template<class K,class V,class Cmp=std::less<K> >
struct STLMultiMap
{
  typedef std::multimap<K,V,Cmp,Cross::UserSTLAllocator<std::pair<const K,V> > > type;
};

template<class K,class Cmp=std::less<K> >
struct STLSet
{
  typedef std::set<K,Cmp,Cross::UserSTLAllocator<K> > type;
};

template<class T>
struct STLVector
{
  typedef std::vector<T,Cross::UserSTLAllocator<T> > type;
};

template<class T>
struct STLList
{
  typedef std::list<T,Cross::UserSTLAllocator<T> > type;
};

template<class T>
struct STLDeque
{
  typedef std::deque<T,Cross::UserSTLAllocator<T> > type;
};

template<class T>
struct STLQueue
{
  typedef std::queue<T,typename STLDeque<T>::type> type;
};

template<class T,class Traits=std::char_traits<T> >
struct STLBasicString
{
  typedef std::basic_string<T,Traits,Cross::UserSTLAllocator<T> > type;
};
typedef STLBasicString<char>::type String;

template<class T,class Traits=std::char_traits<T> >
struct STLBasicStringStream
{
  typedef std::basic_stringstream<T,Traits,Cross::UserSTLAllocator<T> > type;
};
typedef STLBasicStringStream<char>::type  STLStringStream;



#define DEFINE_OWN_MEM_OPERATION \
  static void *operator new(size_t size){return Cross::GetAllocator()->alloc(size);} \
  static void operator delete(void *p,size_t size){if(p) Cross::GetAllocator()->free(p,size);}


#endif//_NETWORK_MEM_H_
